#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "log/log.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    // 设置标题图标
    setWindowTitle("信息管理系统");
    setWindowIcon(QIcon(":/image/picture/main.png"));

    // 添加所需要的背景图片到集合中存储起来
    addBackGroundImageime();

    // 初始化时加载一次背景设置
    changeBackGroundImage();

    // 定时改变背景图片
    changeBackGroundImageime = new QTimer(this);
    connect(changeBackGroundImageime,SIGNAL(timeout()),this,SLOT(changeBackGroundImage()));
    changeBackGroundImageime->start(3000);

    // 设置左侧的分类列表不聚焦，也就是取消白色虚线
    ui->classify_listWidget->setFocusPolicy(Qt::NoFocus);

    // 打开数据库
    openDataBase();

    // 创建自定义字段表
    bool isSuccess = DataBaseOpt::createColumnSqlTable();
    if(isSuccess) {
        // 创建成功则添加默认数据，也就是默认的学生表信息
        insertToColumnTableDefaultColumns();
    }

    // 创建自定义表
    isSuccess = DataBaseOpt::createUserDefineSqlTable();
    if(isSuccess) {
        // 创建成功则添加默认数据，也就是默认的学生表名信息
        insertToUserdefineTableDefaultTableName();
    }

    // 创建学生表
    createStudentSqlTable();

    // 初始化分类列表数据，返回得到列表对应自定义表信息集合
    QList<UserDefineTableEntity> entitys = initClassifyListWidget();

    // 下面用分割器替换界面的最外层的widget，使得可以左右拖动，因为界面没有分割器，只有用这种方式进行替换，如果是纯代码写的界面，不存在这种问题
    mainSplitter = new QSplitter(Qt::Horizontal);//新建水平分割器
    mainSplitter->setHandleWidth(3);//分割线的宽度
    mainSplitter->setChildrenCollapsible(false);//不允许把分割出的子窗口拖小到0，最小值被限定为sizeHint或maxSize/minSize
    mainSplitter->addWidget(ui->classify_listWidget);//把ui中的列表组件拿走，放到分割器里面

    // 新建一个自定义含表格的界面CommonForm，将它添加进分割器中
    UserDefineTableEntity userDefineTableEntity;
    userDefineTableEntity.tableName = "";
    userDefineTableEntity.tableZnName = "";
    if(!ObjectUtil::isEmpty(entitys)) {
        userDefineTableEntity = entitys.at(0); // 以第1个自定义表信息作为界面初始化表格信息
    }
    CommonForm* commonForm = new CommonForm(this);
    commonForm->loadView(userDefineTableEntity); // 传入该界面对应的表信息，让其根据此信息加载界面样式
    mainSplitter->addWidget(commonForm); // 将自定义表格界面组件CommonForm添加到分割器里面
    tableAndWidgetMap.insert(userDefineTableEntity.tableZnName, commonForm); // 添加表中文名和界面组件CommonForm的映射关系

    // 将界面的最外层QWidget替换成分割器，这样就形成了左右分割的样式
    this->centralWidget()->layout()->replaceWidget(ui->all_widget, mainSplitter);//把ui中拖出的容器QWidget换成分割器

    ui->progressBar->setValue(100);
    // 隐藏工具栏和状态栏
    this->statusBar()->hide();
    ui->mainToolBar->setVisible (false);
}

MainWindow::~MainWindow()
{
    delete changeBackGroundImageime;
    delete mainSplitter;
    // 循环删除界面右侧Form组件对象
    QList<CommonForm*> commonForms =  tableAndWidgetMap.values();
    for(CommonForm* commonForm: commonForms) {
        delete commonForm;
    }
    // 清理映射集
    tableAndWidgetMap.clear();
    delete ui;
}

//==========================================向背景集合中添加背景图片=================================
void MainWindow::addBackGroundImageime()
{
    backgroundImages.append(":/image/picture/picture_1.jpg");
    backgroundImages.append(":/image/picture/picture_2.jpg");
    backgroundImages.append(":/image/picture/picture_3.jpg");
    backgroundImages.append(":/image/picture/picture_4.jpg");
    backgroundImages.append(":/image/picture/picture_5.jpg");
}

//==========================================打开数据库=================================
void MainWindow::openDataBase()
{
    DataBaseManage::openDb();
}

//==========================================创建学生表=================================
bool MainWindow::createStudentSqlTable()
{
    QList<QPair<QString,QString>> defaultColumns = getDefaultColumns();
    QList<QString> columns;
    for(QPair<QString,QString> column: defaultColumns){
        columns.append(column.first);
    }
    return DataBaseOpt::createTable(UserDefineConstant::STUDENT_TABLE_NAME, columns);
}

//==========================================获得默认字段信息（也就是学生字段信息）=================================
QList<QPair<QString,QString>> MainWindow::getDefaultColumns()
{
    QList<QPair<QString,QString>> columns;
    columns.append(qMakePair(QString("student_name"),QString("姓名")));
    columns.append(qMakePair(QString("student_number"),QString("学号")));
    columns.append(qMakePair(QString("student_college"),QString("学院")));
    columns.append(qMakePair(QString("student_age"),QString("年龄")));
    columns.append(qMakePair(QString("student_sex"),QString("性别")));
    return columns;
}

//==========================================向自定义表插入默认数据（也就是学生表的表名信息）=================================
void MainWindow::insertToUserdefineTableDefaultTableName()
{
    QList<QPair<QString,QString>> columnNameAndValues;
    columnNameAndValues.append(qMakePair(QString(UserDefineConstant::USERDEFINE_TABLE_COLUMN_TABLE_NAME), UserDefineConstant::STUDENT_TABLE_NAME));
    columnNameAndValues.append(qMakePair(QString(UserDefineConstant::USERDEFINE_TABLE_COLUMN_TABLE_ZN_NAME), UserDefineConstant::STUDENT_TABLE_ZN_NAME));
    DataBaseOpt::insertTableData(UserDefineConstant::USERDEFINE_TABLE_TABLE_NAME, columnNameAndValues);
}

//==========================================向自定义字段表插入默认数据（也就是学生表的字段信息）=================================
void MainWindow::insertToColumnTableDefaultColumns()
{
    QList<QPair<QString,QString>> defaultColumns = getDefaultColumns();
    QList<QPair<QString,QString>> columnNameAndValues;
    for(QPair<QString,QString> column: defaultColumns) {
        columnNameAndValues.append(qMakePair(QString(UserDefineConstant::TABLE_CONNECT_TABLE), UserDefineConstant::STUDENT_TABLE_NAME));
        columnNameAndValues.append(qMakePair(QString(UserDefineConstant::TABLE_COLUMN_NAME), QString(column.first)));
        columnNameAndValues.append(qMakePair(QString(UserDefineConstant::TABLE_COLUMN_ZN_NAME), QString(column.second)));
        columnNameAndValues.append(qMakePair(QString(UserDefineConstant::TABLE_COLUMN_IS_UNIQUE), QString(UserDefineConstant::BOOL_ZN_NAME_FALSE)));
        columnNameAndValues.append(qMakePair(QString(UserDefineConstant::TABLE_COLUMN_IS_REQUIRED), QString(UserDefineConstant::BOOL_ZN_NAME_TRUE)));
        DataBaseOpt::insertTableData(UserDefineConstant::COLUMN_TABLE_NAME, columnNameAndValues);
        columnNameAndValues.clear();
    }
}

//==========================================初始化左侧表中文名列表（分类列表）=================================
QList<UserDefineTableEntity> MainWindow::initClassifyListWidget()
{
    ui->classify_listWidget->clear();
    QList<UserDefineTableEntity> userdefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(QList<QueryConditions>());
    QList<QString> tableZnNames;
    for(UserDefineTableEntity entity: userdefineTableEntitys) {
        tableZnNames.append(entity.tableZnName);
    }
    QStringList tableNamesList = QStringList(tableZnNames);
    ui->classify_listWidget->addItems(tableNamesList);
    if(!ObjectUtil::isEmpty(tableZnNames)) {
        ui->classify_listWidget->setCurrentRow(0);
    }
    return userdefineTableEntitys;
}

//==========================================改变背景显示图片=================================
void MainWindow::changeBackGroundImage()
{
    if(nowBackgroundImagesIndex < backgroundImages.size()) {
        QPixmap pixmap = QPixmap(backgroundImages.at(nowBackgroundImagesIndex)).scaled(this->size());
        QPalette palette(this->palette());
        palette.setBrush(QPalette::Background, QBrush(pixmap));
        this->setPalette(palette);
        nowBackgroundImagesIndex++;
    } else {
        nowBackgroundImagesIndex = 0;
    }
}

//==========================================改变进度条的值=================================
void MainWindow::changeProgressBarVal()
{
    // 单次单位时间的值
    double unitVal = (double) progressBarFanalVal / progressFixedCount;
    qCritical()<<"测试进入进度条值：progressBarFanalVal：" << QString::number(progressBarFanalVal) << ",progressFixedCount: " << progressFixedCount
              << ",unitVal:" << QString::number(unitVal);
    // 如果指定次数后的值比预定的最终值小，则直接设置，如果计算后的值比预定最终值大，则直接设置为最终值
    progressBarNowVal = progressBarNowVal + unitVal;
    qCritical()<<"测试进入进度条：" << QString::number(progressBarNowVal);
    if (progressBarNowVal < progressBarFanalVal) {
        ui->progressBar->setValue(progressBarNowVal);
    } else {
        ui->progressBar->setValue(progressBarFanalVal);
    }
}

//==============刷新左侧列表信息到最新，和刷新指定右侧tableName对应表格界面组件CommionForm所有界面信息（该方法主要针对新增、删除、修改表字段后的刷新操作，和新增表后的刷新操作）==================================
void MainWindow::refreshClassifyListWidgetAndTableWidgetByTableName(QString tableName)
{
    // 构造查询条件
    QList<QueryConditions> conditions;
    conditions.append(QueryConditions(UserDefineConstant::USERDEFINE_TABLE_COLUMN_TABLE_NAME, tableName, false, "=", "and"));
    // 查询出自定义表中指定tableName对应的数据
    QList<UserDefineTableEntity> userdefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(conditions);
    UserDefineTableEntity entity = userdefineTableEntitys.at(0);
    // 调用刷新左侧列表信息，和刷新指定右侧tableZnName表格界面所有的界面信息方法
    refreshClassifyListWidgetAndTableWidgetByTableZnName(entity.tableZnName);
}

//==============刷新左侧列表信息到最新，和刷新指定右侧tableZnName对应表格界面组件CommionForm所有界面信息（该方法主要针对新增、删除、修改表字段后的刷新操作，和新增表后的刷新操作）==================================
void MainWindow::refreshClassifyListWidgetAndTableWidgetByTableZnName(QString tableZnName)
{
    //---------------------更新左侧列表数据为最新的数据显示--------------------
    // 获取当前左侧表名信息列表选中的行
    QListWidgetItem* currentItem = ui->classify_listWidget->currentItem();
    QString checkTableZnName = currentItem->text(); // 选中列表行的中文名称
    ui->classify_listWidget->clear(); // 清除列表所有信息
    // 查询数据库中所有的表名信息集合
    QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(QList<QueryConditions>());
    QList<QString> tableZnNames;
    int checkIndex = 0; // 选中行的索引值
    int row = 0;
    for(UserDefineTableEntity entity: userDefineTableEntitys) {
        tableZnNames.append(entity.tableZnName);
        if(entity.tableZnName == checkTableZnName) {
            checkIndex = row; // 记录下之前已经选中的列表行索引
        }
        row++;
    }
    QStringList tableNamesList = QStringList(tableZnNames);
    ui->classify_listWidget->addItems(tableNamesList); // 添加所有的表名信息集合到左侧列表中
    if(!ObjectUtil::isEmpty(tableZnNames)) {
        ui->classify_listWidget->setCurrentRow(checkIndex); // 选中之前选中的行
    }

    //---------------------刷新指定tableZnName对应的CommonForm界面组件的数据--------------------
    // 创建或者得到指定tableZnName对应的CommonForm界面组件对象，传入false不替换右侧列表显示界面数据，因为这里只对tableZnName对应的CommonForm进行数据刷新，不替换界面显示
    CommonForm* commonForm = replaceOrAddTableWidgetShow(tableZnName, false);
    // 刷新界面的条件下拉框
    commonForm->updateSelectColumnCombobox();
    // 刷新界面的显示隐藏列下拉框
    commonForm->updateColumnHideShowCombobox();
    // 刷新界面列表头
    commonForm->updateUserdefineQTableWidgetHeader();
    // 刷新界面表格数据
    commonForm->autoUserdefineTableReflash(false);
    // 自动调整界面表格列表宽度
    commonForm->autoAdjustmentTableWidth();
}

//==============刷新左侧列表信息到最新，和刷新指定右侧tableZnName对应表格界面组件CommionForm所有界面信息（该方法主要针对删除表后的刷新操作）==================================
void MainWindow::refreshClassifyListWidgetAndTableWidget() {
    //---------------------更新左侧列表数据为最新的数据显示--------------------
    // 获取当前左侧表名信息列表选中的行
    QListWidgetItem* currentItem = ui->classify_listWidget->currentItem();
    QString checkTableZnName = currentItem->text(); // 选中列表行的中文名称
    // 查询数据库中所有的表名信息集合
    QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(QList<QueryConditions>());
    QList<QString> tableZnNames;
    int checkIndex = 0; // 选中行的索引值
    int row = 0;
    for(UserDefineTableEntity entity: userDefineTableEntitys) {
        tableZnNames.append(entity.tableZnName);
        if(entity.tableZnName == checkTableZnName) {
            checkIndex = row; // 记录下之前已经选中的列表行索引
        }
        row++;
    }
    ui->classify_listWidget->clear(); // 清除列表所有信息
    QStringList tableNamesList = QStringList(tableZnNames);
    ui->classify_listWidget->addItems(tableNamesList); // 添加所有的表名信息集合到左侧列表中
    if(!ObjectUtil::isEmpty(tableZnNames)) {
        ui->classify_listWidget->setCurrentRow(checkIndex); // 选中之前选中的行,如果选中的行已经不存在，则默认会选中第一行
    }

    // 找出已经不存在的表名
    QList<QString> removeTables;
    for(QString tableZnName : tableAndWidgetMap.keys()) {
        if(!tableZnNames.contains(tableZnName)) {
            removeTables.append(tableZnName);
        }
    }

    // 移除不存在的映射关系
    for(QString tableZnName : removeTables) {
        tableAndWidgetMap.remove(tableZnName);
    }

    // 如果选中列为第一列时，则显示为第一列
    if(checkIndex == 0) {
        CommonForm* commonForm = replaceOrAddTableWidgetShow(tableZnNames.at(0), true);
        // 刷新界面的条件下拉框
        commonForm->updateSelectColumnCombobox();
        // 刷新界面的显示隐藏列下拉框
        commonForm->updateColumnHideShowCombobox();
        // 刷新界面列表头
        commonForm->updateUserdefineQTableWidgetHeader();
        // 刷新界面表格数据
        commonForm->autoUserdefineTableReflash(false);
        // 自动调整界面表格列表宽度
        commonForm->autoAdjustmentTableWidth();
    }
}

//==============刷新左侧列表信息到最新，替换老的表中文名和CommionForm映射为新的表名和新的CommionForm映射（该方法主要针对修改表名后的刷新操作）==================================
void MainWindow::replaceAndRefreshClassifyListWidgetAndTableWidget(QString oldTableZnName, QString newTableZnName)
{
    //---------------------更新左侧列表数据为最新的数据显示--------------------
    // 获取当前左侧表名信息列表选中的行
    QListWidgetItem* currentItem = ui->classify_listWidget->currentItem();
    QString checkTableZnName = currentItem->text(); // 选中列表行的中文名称
    // 查询数据库中所有的表名信息集合
    QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(QList<QueryConditions>());
    QList<QString> tableZnNames;
    int checkIndex = 0; // 选中行的索引值
    int row = 0;
    for(UserDefineTableEntity entity: userDefineTableEntitys) {
        tableZnNames.append(entity.tableZnName);
        if((entity.tableZnName == checkTableZnName) ||
                (checkTableZnName == oldTableZnName && entity.tableZnName == newTableZnName)) {
            checkIndex = row; // 记录下之前已经选中的列表行索引
        }
        row++;
    }
    if(!tableZnNames.contains(newTableZnName)) {
        qCritical()<<"替换刷新主界面左侧列表和右侧表格时，查询数据库中，用户自定义表不存在 "<<newTableZnName<<" 表";
        return;
    }
    ui->classify_listWidget->clear(); // 清除列表所有信息
    QStringList tableNamesList = QStringList(tableZnNames);
    ui->classify_listWidget->addItems(tableNamesList); // 添加所有的表名信息集合到左侧列表中
    if(!ObjectUtil::isEmpty(tableZnNames)) {
        ui->classify_listWidget->setCurrentRow(checkIndex); // 选中之前选中的行
    }

    // 移除老的映射关系
    if(tableAndWidgetMap.contains(oldTableZnName)) {
        tableAndWidgetMap.remove(oldTableZnName);
    }
    CommonForm* commonForm = NULL;
    // 如果选中列表项是刚好修改的表，则替换为最新的显示
    if(tableZnNames.at(checkIndex) == newTableZnName) {
        commonForm = replaceOrAddTableWidgetShow(newTableZnName, true);
    } else {
        commonForm = replaceOrAddTableWidgetShow(newTableZnName, false);
    }
    // 刷新界面的条件下拉框
    commonForm->updateSelectColumnCombobox();
    // 刷新界面的显示隐藏列下拉框
    commonForm->updateColumnHideShowCombobox();
    // 刷新界面列表头
    commonForm->updateUserdefineQTableWidgetHeader();
    // 刷新界面表格数据
    commonForm->autoUserdefineTableReflash(false);
    // 自动调整界面表格列表宽度
    commonForm->autoAdjustmentTableWidth();
}

//==============添加tableZnName对应的CommonForm进映射关系,同时根据isReplaceShow设置进行替换右侧表格显示，指定是否用tableZnName对应的CommonForm替换界面右侧的正在展示的表界面组件CommonForm信息=============
CommonForm* MainWindow::replaceOrAddTableWidgetShow(QString tableZnName, bool isReplaceShow)
{
    if(tableAndWidgetMap.contains(tableZnName)) {
        CommonForm* form = tableAndWidgetMap.value(tableZnName);
        if(isReplaceShow) {
           mainSplitter->replaceWidget(1, form);
        }
        return form;
    } else {
        QList<QueryConditions> conditions;
        conditions.append(QueryConditions(UserDefineConstant::USERDEFINE_TABLE_COLUMN_TABLE_ZN_NAME,
                                          tableZnName, false, "=", "and"));
        QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(conditions);
        UserDefineTableEntity entity = userDefineTableEntitys.at(0);
        CommonForm* commonForm = new CommonForm(this);
        commonForm->loadView(entity); // 传入该界面对应的表格信息，让其根据此信息加载界面样式
        tableAndWidgetMap.insert(entity.tableZnName, commonForm);
        if(isReplaceShow) {
            mainSplitter->replaceWidget(1, commonForm);
        }
        return commonForm;
    }
}

//==========================================改变进度条进度=================================
void MainWindow::changeProgressBar(int time, int val)
{
    if(progressBarTimer == NULL || progressBarTimer == nullptr) {
        progressBarTimer = new QTimer();
        connect(progressBarTimer,SIGNAL(timeout()),this,SLOT(changeProgressBarVal()));
    } else {
        if (progressBarTimer->isActive()) {
            progressBarTimer->stop();
        }
    }
    // 设置进度条为初始值0
    ui->progressBar->setValue(0);
    // 进度条最终值
    progressBarFanalVal = val;
    // 进度条当前值(恢复初始值)
    progressBarNowVal = 0.00;
    // 进度条指定到达时间（秒）
    progressTime = time;
    if (time <= 0) {
        ui->progressBar->setValue(progressBarFanalVal);
    } else {
        // 定时器间隔执行时间（到达时间乘1000转成毫秒值，除以固定执行次数，等于每次需要间隔的时间）
        int uniTime = (time * 1000) / progressFixedCount;
        progressBarTimer->setInterval(uniTime);
        progressBarTimer->start();
    }
}

//==========================================左侧分类列表-列表项点击事件=================================
void MainWindow::on_classify_listWidget_itemClicked(QListWidgetItem *item)
{
    QString tableZnName = item->text().trimmed();
    qDebug()<<"列表项点击事件:"<<tableZnName;
    replaceOrAddTableWidgetShow(tableZnName, true);
}
